package myBot;

import robocode.*;
import robocode.util.Utils;

import java.io.IOException;
import java.io.PrintStream;
import java.lang.Math;

import data.Generation;



public class myBot extends AdvancedRobot {

	static PrintStream w = null;

	static Generation currentGeneration = new Generation();
	
	static int generation=0;
	static int individ=0;
	
	data.MovementData individual = new data.MovementData();
	double velocity=0;
	double turnrate=0;

	
	public void run(){

	int bestvalue=0;
		int best=0;
		int total=0;
		this.setTurnRadarRightRadians(Double.POSITIVE_INFINITY); 
		if(individ == currentGeneration.generationpopulation.length)
		{
			for(int i = 0; i < currentGeneration.generationpopulation.length;i++)
			{
				total += currentGeneration.generationpopulation[i].Fitness;
				
				if(currentGeneration.generationpopulation[i].Fitness>bestvalue)
				{
					bestvalue = currentGeneration.generationpopulation[i].Fitness;
					best = i;
				}
			}

			try 
			{
				if(w == null)
					w = new PrintStream(new RobocodeFileOutputStream(getDataFile("count.dat")));

				w.println(bestvalue + "\t" + (total/currentGeneration.generationpopulation.length));
				w.println(currentGeneration.generationpopulation[best].speedData.bearing + "\t" + currentGeneration.generationpopulation[best].speedData.distanceToEnemy);
				if(bestvalue > 1000)
				{
					w.println(bestvalue + "  Gen: " + generation);
					w.println(currentGeneration.generationpopulation[best].speedData.bearing + "\t" + currentGeneration.generationpopulation[best].speedData.distanceToEnemy + "\t" + currentGeneration.generationpopulation[best].speedData.headingEnemy + "\t" + currentGeneration.generationpopulation[best].speedData.robotBackDistanceToWall + "\t" + currentGeneration.generationpopulation[best].speedData.robotFrontDistanceToWall + "\t" + currentGeneration.generationpopulation[best].speedData.robotLeftDistanceToWall + "\t" + currentGeneration.generationpopulation[best].speedData.robotRightDistanceToWall + "\t" + currentGeneration.generationpopulation[best].speedData.velocity);
					w.println(currentGeneration.generationpopulation[best].turnData.bearing + "\t" + currentGeneration.generationpopulation[best].turnData.distanceToEnemy + "\t" + currentGeneration.generationpopulation[best].turnData.headingEnemy + "\t" + currentGeneration.generationpopulation[best].turnData.robotBackDistanceToWall + "\t" + currentGeneration.generationpopulation[best].turnData.robotFrontDistanceToWall + "\t" + currentGeneration.generationpopulation[best].turnData.robotLeftDistanceToWall + "\t" + currentGeneration.generationpopulation[best].turnData.robotRightDistanceToWall + "\t" + currentGeneration.generationpopulation[best].turnData.velocity);
				}
				if (w.checkError()) 
				{
					out.println("I could not write the count!");
				}
			} 
			catch (IOException e) 
			{
				out.println("IOException trying to write: ");
				e.printStackTrace(out);
			}
			
			data.Breeding.newGeneration(currentGeneration.generationpopulation);
			individ=0;
			generation+=1;
		}
		
		this.individual=data.MovementData.getobject(currentGeneration.generationpopulation, individ);
		this.setAdjustGunForRobotTurn(true);
		this.setAdjustRadarForGunTurn(true);
		
		do 
		{
			turnRadarRightRadians(Double.POSITIVE_INFINITY); 
		} while (true);

	}
	public void	onScannedRobot(ScannedRobotEvent e){
		velocity = currentGeneration.Evaluator(individual.speedData, e, this);
		turnrate = currentGeneration.Evaluator(individual.turnData,e, this);

		this.setAhead(velocity*8.5);
		this.setTurnRightRadians((turnrate*10*Math.PI)/150);
		this.setTurnRadarRightRadians(Utils.normalRelativeAngle(getHeadingRadians() + e.getBearingRadians() - getRadarHeadingRadians()) * 1.5);	
	}

	public void onRoundEnded(RoundEndedEvent event)
	{
		int roundsPerBot = 1000;

		if(event.getRound() % roundsPerBot == 0)
		{
			this.individual.Fitness=(int) event.getTime();
			currentGeneration.generationpopulation[individ]=this.individual;   
		}
		else if((event.getRound() + 1) % roundsPerBot == 0)
		{
			this.individual.Fitness = (this.individual.Fitness + (int) event.getTime())/roundsPerBot;
			currentGeneration.generationpopulation[individ]=this.individual;
			individ++;
		}
		else
		{
			this.individual.Fitness +=(int) event.getTime();
			currentGeneration.generationpopulation[individ]=this.individual;
		}
	}

	public void onBattleEnded(BattleEndedEvent event)
	{
		w.close();
	}


}
